﻿// Created by Windward Studios - no copyright is claimed. This code can be used in
// any manner by anyone for any reason. There is no copyright of any kind on it. You may
// use it in commercial products. You may change it without sharing those changes.
// We ask that you keep the "created by Windward Studios" in a comment at the top.

using System;
using System.Collections.Specialized;
using System.Configuration;
using System.Data;
using System.Data.Common;
using System.IO;
using net.windward.utils.ado.Access;
using NUnit.Framework;

// bugbug - kailua test DB - create the DB, test it
// uname/pw, trusted conn.
// insert.

namespace net.windward.utils.ado
{
	[TestFixture]
	public class TestAccessProvider
	{
		private string serverName;
		private string username;
		private string password;

		readonly DbProviderFactory providerFactory = DbProviderFactories.GetFactory(WrAccessVendor.FactoryClass);


		[SetUp]
		public void Init()
		{
			NameValueCollection appSettings = ConfigurationManager.AppSettings;
			serverName = Path.GetFullPath(appSettings["AccessServer"]);
			username = appSettings["AccessUsername"];
			password = appSettings["AccessPassword"];
		}

		[Test]
		public void TestCreateProvider()
		{

			// no 64-bit provider
			if (IntPtr.Size != 4)
			{
				Assert.IsFalse(new WrAccessVendor().IsInstalled);
				return;
			}

			Assert.IsTrue(new WrAccessVendor().IsInstalled);

			WrAccessVendor vendor = new WrAccessVendor("My Access name", null, WrAccessVendor.FactoryClass);
			Assert.IsNotNull(vendor);
			Assert.AreEqual(false, vendor.CanEnumerateDatabases);
			Assert.AreEqual(false, vendor.CanEnumerateServers);
			Assert.AreEqual(false, vendor.CanLaunchAdministrator);
			Assert.AreEqual(false, vendor.CanRunScripts);
			Assert.AreEqual(true, vendor.CanUseTrustedConnection);
			Assert.AreEqual(WrVendor.DATABASE_MODE.NEVER, vendor.DatabaseMode);
			Assert.AreEqual(true, vendor.HasProviders);
			Assert.AreEqual("My Access name", vendor.Name);

			Assert.IsTrue(vendor.GetOdbcProviders().Length > 0);
			vendor.OdbcProvider = vendor.GetOdbcProviders()[0].Driver;
			Assert.AreEqual(string.Format("Driver={{{0}}};Dbq={1};Uid=123;Pwd=456", vendor.OdbcProvider, serverName),
				vendor.ConnectionString(serverName, "def", new WrCredentials("123", "456"), true));
		}

		[Test]
		public void TestNorthwindEnumeration()
		{

			// no 64-bit provider
			if (IntPtr.Size != 4)
				return;

			// get the database
			WrAccessVendor vendor = new WrAccessVendor("My Access name", null, WrAccessVendor.FactoryClass);
			WrVendor.OdbcDriverInfo[] odi = vendor.GetOdbcProviders();
			string odbcProvider = null;
			foreach (WrVendor.OdbcDriverInfo odiOn in odi)
				if (odiOn.Driver.Contains("*.accdb"))
				{
					odbcProvider = odiOn.Driver;
					break;
				}
				else
					if (odiOn.Driver.Contains("Access Driver"))
						odbcProvider = odiOn.Driver;
			if (odbcProvider == null)
				odbcProvider = odi[0].Driver;
			WrAccessServer server = new WrAccessServer(providerFactory, odbcProvider, serverName);
			Assert.AreEqual(serverName, server.Name);
			WrAccessDatabase db = new WrAccessDatabase(providerFactory, odbcProvider, serverName);

			// Northwind tables
			db.LoadMetadata(new WrCredentials(username, password), WrVendor.ELEM_OWNER.USER | WrVendor.ELEM_OWNER.META_DATA, null);
			WrTable[] tables = db.Tables;
			Assert.AreEqual(8, tables.Length);
			Assert.AreEqual("Categories", tables[0].FullName);
			Assert.IsFalse(tables[0].IsSystem);
			Assert.AreEqual("Suppliers", tables[7].FullName);
			Assert.IsFalse(tables[7].IsSystem);

			// Northwind views
			WrView[] views = db.Views;
			Assert.AreEqual(18, views.Length);
			Assert.AreEqual("Alphabetical List of Products", views[0].FullName);
			Assert.IsFalse(views[0].IsSystem);
			Assert.AreEqual("Invoices Filter", views[6].FullName);
			Assert.IsFalse(views[6].IsSystem);

			// Northwind.Orders columns
			WrColumn[] cols = db.Tables[4].Columns;
			Assert.AreEqual(14, cols.Length);
			Assert.AreEqual("OrderID", cols[0].FullName);
			Assert.AreEqual(DbType.Int32, cols[0].DbType);
			Assert.AreEqual(null, cols[0].PrimaryKey);

			Assert.AreEqual("CustomerID", cols[1].FullName);
			Assert.AreEqual(DbType.AnsiString, cols[1].DbType);
//bugbug			Assert.AreEqual("Customers.CustomerID", cols[1].PrimaryKey);

			Assert.AreEqual("EmployeeID", cols[2].FullName);
			Assert.AreEqual(DbType.Int32, cols[2].DbType);
//bugbug			Assert.AreEqual("Employees.EmployeeID", cols[2].PrimaryKey);

			Assert.AreEqual("ShipCountry", cols[13].FullName);
			Assert.AreEqual(DbType.AnsiString, cols[13].DbType);
			Assert.AreEqual(null, cols[13].PrimaryKey);
		}
	}
}
